package com.eenie.onecloud.controllers;


import com.alibaba.fastjson.JSON;
import com.eenie.onecloud.configs.AccountConfig;
import com.eenie.onecloud.req.WantGoodReq;
import com.eenie.onecloud.res.GoodDetailRes;
import com.eenie.onecloud.res.GoodListRes;
import com.eenie.onecloud.res.NormalRes;
import com.eenie.onecloud.services.OneCloudApi;
import com.eenie.onecloud.services.OneCloudMallApi;
import com.eenie.onecloud.utils.MD5Utils;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.*;
import retrofit2.Response;

import java.io.IOException;
import java.util.*;

@Component
@RestController
public class OneCloudController {
    @Autowired
    private OneCloudMallApi mOneCloudMallApi;

    @Autowired
    private OneCloudApi mOneCloudApi;


    private List<GoodListRes.DataBean.ListsBean> AllGoods = new ArrayList<>();
    private Map<Integer, GoodListRes.DataBean.ListsBean> wantGoodsMap = new HashMap<>();
    private List<GoodListRes.DataBean.ListsBean> needSubmit = new ArrayList<>();
    private long lastSubmitTime;

    @Scheduled(fixedDelay = 10000)
    @RequestMapping(value = "/fetchGoods", method = RequestMethod.GET)
    public String fetchGoods() throws IOException {
        if (AllGoods == null || AllGoods.isEmpty()) {
            AllGoods = updateStock();
        }
        System.out.println("====================================================\n=");
        System.out.println("=  正在监控ID：" + JSON.toJSONString(wantGoodsMap.keySet()) + "\n=");

        int n = 0;
        for (GoodListRes.DataBean.ListsBean bean : AllGoods) {
            int isSoldout = fetchGoodDetail(bean);
            if (wantGoodsMap.containsKey(bean.getGoodsid()) && isSoldout == 1 && (lastSubmitTime == 0 || (System.currentTimeMillis() - lastSubmitTime >= 30 * 60 * 1000))) {
                needSubmit.add(bean);
            }
            if (isSoldout == 1) {
                n++;
                System.out.println("=  " + java.lang.String.format("%s、%s(%s) - 销量%s", n, bean.getName(), bean.getGoodsid(), bean.getExchange_num()));
            }
        }
        System.out.println("=\n====================================================\n");
        if (!needSubmit.isEmpty()) {
            StringBuffer sb = new StringBuffer();
            for (GoodListRes.DataBean.ListsBean listsBean : needSubmit) {
                sb.append(listsBean.getName() + "--");
            }
            sb.append("有货啦！！！！正在尝试抢购！！");
            push("有货通知", sb.toString());
            needSubmit.clear();
//            submitOrders();
        }
        return JSON.toJSONString(AllGoods);
    }

    @PostMapping(value = "/updateWantGoods")
    public String updateWantGoods(@org.springframework.web.bind.annotation.RequestBody Map<String, Object> reqMap) throws IOException {
        wantGoodsMap.clear();
        WantGoodReq wantGoodReq = JSON.parseObject(JSON.toJSONString(reqMap), WantGoodReq.class);
        if (wantGoodReq != null) {
            for (GoodListRes.DataBean.ListsBean allGood : AllGoods) {
                if (wantGoodReq.getWant_ids().contains(allGood.getGoodsid())) {
                    wantGoodsMap.put(allGood.getGoodsid(), allGood);
                }
            }
        }
        return JSON.toJSONString(wantGoodsMap.values());
    }

    @RequestMapping(value = "/getWantGoods", method = RequestMethod.GET)
    public String getWantGoods() throws IOException {
        return JSON.toJSONString(wantGoodsMap.values());
    }

    private Map<String, Object> creactOrder(GoodListRes.DataBean.ListsBean g) {
        Map<String, Object> orderMap = new HashMap<>();
        List<Map<String, Object>> orders = new ArrayList<>();
        Map<String, Object> singleOrderMap = new HashMap<>();
        singleOrderMap.put("businessid", g.getBusinessid());
        singleOrderMap.put("goodsid", g.getGoodsid());
        singleOrderMap.put("name", g.getName());
        singleOrderMap.put("num", 1);
        singleOrderMap.put("price", g.getExchange_price());
        orders.add(singleOrderMap);
        orderMap.put("orders", orders);
        return orderMap;
    }


    private int fetchGoodDetail(GoodListRes.DataBean.ListsBean good) throws IOException {
        FormBody body = new FormBody.Builder()
                .add("goodsid", String.valueOf(good.getGoodsid()))
                .build();
        GoodDetailRes res = mOneCloudMallApi.fetchGoodDetail(body).execute().body();

        if (res.getIRet() == 0) {
            good.setExchange_num(res.getData().getExchange_num());
            good.setIs_soldout(res.getData().getIs_soldout());
            return res.getData().getIs_soldout();
        } else {
            login();
            return 0;
        }


    }

    private NormalRes submitOrders(Map<String, Object> params) throws IOException {
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=UTF-8"), JSON.toJSONString(params));
        return mOneCloudMallApi.submitOrders(body).execute().body();
    }


    public void submitOrders() throws IOException {
        lastSubmitTime = System.currentTimeMillis();
        for (GoodListRes.DataBean.ListsBean bean : needSubmit) {
            NormalRes res = submitOrders(creactOrder(bean));
            if (res.getIRet() == 0) {
                push("抢购通知", String.format("抢到%s啦，快去付款吧！ - %s", bean.getName(), Calendar.getInstance().getTime()));
            } else {
                push("抢购通知", String.format("抢购%s失败，原因：%s - %s", bean.getName(), res.getSMsg(), Calendar.getInstance().getTime()));
            }
        }
        needSubmit.clear();
    }


    private List<GoodListRes.DataBean.ListsBean> updateStock() throws IOException {
        boolean hasNext = true;
        int page = 1;
        List<GoodListRes.DataBean.ListsBean> goodList = new ArrayList<>();
        while (hasNext) {
            FormBody body = new FormBody.Builder()
                    .add("page", String.valueOf(page))
                    .build();
            Response<GoodListRes> response = mOneCloudMallApi.fetchGoodList(body).execute();

            if (response.body().getIRet() == 0) {
                goodList.addAll(response.body().getData().getLists());
                if (response.body().getData().getNext_page() > 0) {
                    page = response.body().getData().getNext_page();
                    hasNext = true;
                } else {
                    hasNext = false;
                }
            } else {
                login();
            }

        }
        return goodList;
    }


    private void push(String title, String msg) throws IOException {
        mOneCloudMallApi.pushNotice(title, msg).execute();
    }


    @RequestMapping(value = "/pushMsg", method = RequestMethod.GET)
    private String pushMsg(@RequestParam("msg") String msg) throws IOException {
        return mOneCloudMallApi.pushNotice("测试啦！", msg).execute().body().string();
    }


    @RequestMapping(value = "/login", method = RequestMethod.GET)
    private String login() throws IOException {
        Map<String, String> params = new HashMap<>();
        params.put("phone", "18601782405");
        params.put("account_type", "4");
        params.put("deviceid", "97A895EEC780134B");
        params.put("imeiid", "860162035890117");
        params.put("pwd", MD5Utils.pwdMd5("594202"));
        params.put("uuid", "FFFFFFFF-C7A9-9954-0000-00000E08DD20");


        Response<okhttp3.ResponseBody> res = mOneCloudApi.login(mapToBody(params)).execute();

        String sessionid = "";
        String userid = "";

        for (String s : res.headers().values("Set-Cookie")) {
            String[] cookie = s.split(";");
            for (String c : cookie) {
                if (c.contains("sessionid")) {
                    sessionid = c.split("=")[1];
                }
                if (c.contains("userid")) {
                    userid = c.split("=")[1];
                }
            }
        }

        AccountConfig.getInstance().setHeader(sessionid, userid);

        return  AccountConfig.getInstance().getHeader();
    }


    private FormBody mapToBody(Map<String, String> params) {
        Map<String, String> paramTree = new TreeMap<>();
        paramTree.putAll(params);
        StringBuilder sb = new StringBuilder();
        FormBody.Builder builder = new FormBody.Builder();
        for (Map.Entry<String, String> entry : paramTree.entrySet()) {
            builder.add(entry.getKey(), entry.getValue());
            sb.append(java.lang.String.format("%s=%s&", entry.getKey(), entry.getValue()));
        }
        sb.append(java.lang.String.format("%s=%s&", "key", ""));
        builder.add("sign", MD5Utils.MD5(sb.substring(0, sb.length() - 1)));
        return builder.build();
    }


}
